<!DOCTYPE html>
<html>
<!--
Copyright 2012 The Closure Library Authors. All Rights Reserved.

Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<!--
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.labs.observe.ObservationSet</title>
<script src="../../base.js"></script>
<script>
  goog.require('goog.dispose');
  goog.require('goog.labs.observe.ObservableSet');
  goog.require('goog.labs.observe.Observer');
  goog.require('goog.labs.observe.SimpleObservable');
  goog.require('goog.testing.jsunit');
  goog.require('goog.testing.recordFunction');
</script>
</head>
<body>
<script>
var observable1;
var observable2;
var observableSet;


function setUp() {
  observable1 = new goog.labs.observe.SimpleObservable();
  observable2 = new goog.labs.observe.SimpleObservable();
  observableSet = new goog.labs.observe.ObservableSet();
}


function tearDown() {
  goog.dispose(observable1);
  goog.dispose(observable2);
}


function testAddingObservers() {
  var observerFn1 = goog.testing.recordFunction();
  var observerFn2 = goog.testing.recordFunction();
  assertTrue(observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn1)));
  assertFalse(observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn1)));
  assertTrue(observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn2)));
  assertFalse(observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn2)));
}


function testAddingObservables() {
  assertTrue(observableSet.addObservable(observable1));
  assertFalse(observableSet.addObservable(observable1));
  assertTrue(observableSet.addObservable(observable2));
}


function testRemovingObservers() {
  var observerFn = goog.testing.recordFunction();
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn));
  observableSet.addObservable(observable1);
  observableSet.addObservable(observable2);

  assertTrue(observableSet.removeObserver(
      goog.labs.observe.Observer.fromFunction(observerFn)));
  assertFalse(observableSet.removeObserver(
      goog.labs.observe.Observer.fromFunction(observerFn)));

  observable1.notify();
  observable2.notify();
  assertEquals(0, observerFn.getCallCount());
}


function testRemovingObservables() {
  var observerFn = goog.testing.recordFunction();
  observableSet.addObservable(observable1);
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn));
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn));

  assertTrue(observableSet.removeObservable(observable1));
  assertFalse(observableSet.removeObservable(observable1));

  observable1.notify();
  observable1.notify();
  assertEquals(0, observerFn.getCallCount());
}


function testAddingObserverBeforeAddingObservable() {
  var observerFn = goog.testing.recordFunction();
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn));

  observableSet.addObservable(observable1);
  observableSet.addObservable(observable2);

  observable1.notify();
  assertEquals(1, observerFn.getCallCount());
  observable2.notify();
  assertEquals(2, observerFn.getCallCount());
}


function testAddingObserverAfterAddingObservable() {
  var observerFn1 = goog.testing.recordFunction();
  var observerFn2 = goog.testing.recordFunction();

  observableSet.addObservable(observable1);

  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn1));
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn2));

  observable1.notify();
  assertEquals(1, observerFn1.getCallCount());
  assertEquals(1, observerFn2.getCallCount());
}


function testRemoveAllObservers() {
  var observerFn1 = goog.testing.recordFunction();
  var observerFn2 = goog.testing.recordFunction();

  observableSet.addObservable(observable1);
  observableSet.addObservable(observable2);
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn1));
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn2));

  observableSet.removeAllObservers();

  observable1.notify();
  observable2.notify();
  assertEquals(0, observerFn1.getCallCount());

  // Ensures that the observables are still around.
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn1));
  observable1.notify();
  observable2.notify();
  assertEquals(2, observerFn1.getCallCount());
}


function testRemoveAllObservables() {
  var observerFn1 = goog.testing.recordFunction();
  var observerFn2 = goog.testing.recordFunction();

  observableSet.addObservable(observable1);
  observableSet.addObservable(observable2);
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn1));
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn2));

  observableSet.removeAllObservables();

  observable1.notify();
  observable2.notify();
  assertEquals(0, observerFn1.getCallCount());
  assertEquals(0, observerFn2.getCallCount());

  // Ensures that the observers are still around.
  observableSet.addObservable(observable1);
  observable1.notify();
  assertEquals(1, observerFn1.getCallCount());
  assertEquals(1, observerFn2.getCallCount());
}


function testRemoveAll() {
  var observerFn1 = goog.testing.recordFunction();
  var observerFn2 = goog.testing.recordFunction();

  observableSet.addObservable(observable1);
  observableSet.addObservable(observable2);
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn1));
  observableSet.addObserver(
      goog.labs.observe.Observer.fromFunction(observerFn2));

  observableSet.removeAll();

  observable1.notify();
  observable2.notify();
  assertEquals(0, observerFn1.getCallCount());

  assertEquals(0, observableSet.observers_.length);
  assertEquals(0, observableSet.observables_.length);
}

</script>
</body>
</html>
